﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Management;
using System.Windows.Forms;
using HalconDotNet;
using System.Drawing.Imaging;
using System.Drawing;
using System.Threading.Tasks;
using System.Threading;

namespace YJYpublicClass
{
    class PublicFuntions
    {
        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section,string key,string val,string filepath);
        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filepath);
        /// <summary>
        /// 强制结束进程
        /// </summary>
        public static void KillProcess(string ProcessName)
        {
            Process[] cur = Process.GetProcesses();
            for (int i = 0; i < cur.Length; i++)
            {
                if (cur[i].ProcessName == ProcessName)
                {
                    cur[i].Kill();
                }
            }
        }
        /// <summary>
        /// 超时强制取消
        /// </summary>
        /// <param name="action"></param>
        /// <param name="timeoutMilliseconds"></param>
        /// <exception cref="TimeoutException"></exception>
        public static void ExecuteWithTimeout(Action action, int timeoutMilliseconds)
        {
            var cts = new CancellationTokenSource();
            var task = Task.Run(() =>
            {
                // 传递 CancellationToken 到需要支持取消的代码中
                action();
                cts.Token.ThrowIfCancellationRequested();
            }, cts.Token);

            if (!task.Wait(timeoutMilliseconds))
            {
                cts.Cancel(); // 触发取消
                throw new TimeoutException("操作超时！");
            }
        }
        /// <summary>
        /// 写入数据至INI文件
        /// </summary>
        /// <param name="section"></param>
        /// <param name="key"></param>
        /// <param name="Value"></param>
        /// <param name="Path"></param>
        public static void WriteINI(string section, string key, string Value, string Path)
        {
            WritePrivateProfileString(section, key, Value, Path);
        }

        /// <summary>
        /// 从INI文件读取数据
        /// </summary>
        /// <param name="section"></param>
        /// <param name="key"></param>
        /// <param name="Standard"></param>
        /// <param name="Path"></param>
        /// <returns></returns>
        public static string GetINI(string section, string key, string Standard, string Path)
        {
            StringBuilder temp = new StringBuilder(255);
            GetPrivateProfileString(section, key, Standard, temp, 255, Path);

            return temp.ToString();
        }

        /// <summary>
        /// 查询文件路径是否存在，不存在则根据路径创建文件
        /// </summary>
        /// <param name="FilePath"></param>
        /// <param name="IsCreateFile"></param>
        public static void CreateFile(string FilePath)
        {
            try
            {
                if (System.IO.File.Exists(FilePath) == false)
                {
                    System.IO.Directory.CreateDirectory(FilePath);
                }
            }
            catch (Exception ex)
            {
                SaveErrorLog(PublicValue.LogPath, "CreateFile::" + ex.ToString());
            }
        }

        /// <summary>
        /// 打开任意类型文档
        /// </summary>
        /// <param name="Path"></param>
        public static Boolean OpenDocument(string Path)
        {
            try
            {
                if (System.IO.File.Exists(Path))
                {
                    System.Diagnostics.Process.Start(Path);
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.ToString());
                return false;
            }
        }

        /// <summary>
        /// 获取当前软件的内存占用
        /// </summary>
        public static string GetSoftWareARM()
        {
            try
            {
                Process CurrentProcess = Process.GetCurrentProcess();
                return (CurrentProcess.WorkingSet64 / 1024 / 1024).ToString();
            }
            catch (Exception)
            {
                return "运存获取失败!";
            }
        }

        public static long GetHardDiskSpace(string str_HardDiskName)
        {

            long totalSize = new long();

            str_HardDiskName = str_HardDiskName + ":\\";

            System.IO.DriveInfo[] drives = System.IO.DriveInfo.GetDrives();

            foreach (System.IO.DriveInfo drive in drives)
            {

                if (drive.Name == str_HardDiskName)
                {

                    totalSize = drive.TotalSize / (1024 * 1024 * 1024);

                }

            }

            return totalSize;

        }

        /// <summary>  

        /// 获取指定驱动器的剩余空间总大小(单位为GB)  

        /// </summary>  

        /// <param name=”str_HardDiskName”>只需输入代表驱动器的字母即可 </param>  

        /// <returns> </returns>  

        public static long GetHardDiskFreeSpace(string str_HardDiskName)
        {

            long freeSpace = new long();

            str_HardDiskName = str_HardDiskName + ":\\";

            System.IO.DriveInfo[] drives = System.IO.DriveInfo.GetDrives();

            foreach (System.IO.DriveInfo drive in drives)
            {

                if (drive.Name == str_HardDiskName)
                {

                    freeSpace = drive.TotalFreeSpace / (1024 * 1024 * 1024);

                }

            }

            return freeSpace;

        } 

        /// <summary>
        /// 获取主机网卡编号
        /// </summary>
        /// <returns></returns>
        public static string GetNetWorkMACID()
        {
            try
            {
                string mac = "";
                ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
                ManagementObjectCollection moc = mc.GetInstances();
                foreach (ManagementObject mo in moc)
                {
                    if ((bool)mo["IPEnabled"] == true)
                    {
                        mac += mo["MacAddress"].ToString() + " ";
                        break;
                    }
                }
                moc = null;
                mc = null;
                return mac.Trim();
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.ToString());
                return "uMnIk";
            }
        }

        /// <summary>
        /// 显示图片
        /// </summary>
        /// <param name="ho_Image"></param>
        /// <param name="hv_Window"></param>
        public static void DispImage(HObject ho_Image,HWindow hv_Window)
        {
            HTuple hv_Width,hv_Height;
            
            HOperatorSet.GetImageSize(ho_Image, out hv_Width, out hv_Height);
            HOperatorSet.SetPart(hv_Window,0, 0, hv_Height, hv_Width);
            HOperatorSet.DispObj(ho_Image, hv_Window);
        }
        /// <summary>
        /// COPY FILE
        /// </summary>
        /// <param name="sourcepath"></param>
        /// <param name="targetpath"></param>
        /// <param name="filename"></param>
        /// <param name="isOverride"></param>
        public static void CopyImagebyPath(string sourcepath, string targetpath,string filename, bool isOverride)
        {
            try
            {
                PublicFuntions.CreateFile(targetpath);
                File.Copy(sourcepath, targetpath+ "\\"+filename, isOverride);


            }
            catch (Exception ex)
            {
                MessageBox.Show("图片Copy异常");
                PublicFuntions.SaveErrorLog(PublicValue.LogPath, ex.ToString());
            }
        }
        /// <summary>
        /// 保存图片，jpg格式
        /// </summary>
        /// <param name="hImage"></param>
        /// <param name="path"></param>
        /// <param name="isOK"></param>
        public static void SaveImagebyPath(HObject hImage, string path, bool isOK)
        {
            string SubImageFolder = null;
            try
            {
                string NowTime = null;
                string SaveImageName = null;
                if (isOK)
                
                { 
                    SubImageFolder = path + "\\OKImage\\" + System.DateTime.Now.ToString("yyyyMMdd");
                    PublicFuntions.CreateFile(SubImageFolder);
                    NowTime = System.DateTime.Now.ToString("yyyyMMddHHmmss");
                    SaveImageName = SubImageFolder + "\\" + NowTime + ".jpg";                        //ok原图保存为jpg格式
                    HOperatorSet.WriteImage(hImage, "jpg", 0, SaveImageName);

                }
                else 
                { 
                    SubImageFolder = path + "\\NGImage\\" + System.DateTime.Now.ToString("yyyyMMdd");
                    PublicFuntions.CreateFile(SubImageFolder);
                    NowTime = System.DateTime.Now.ToString("yyyyMMddHHmmss");
                    SaveImageName = SubImageFolder + "\\" + NowTime + ".jpg";                        //ng原图保存为jpg格式
                    HOperatorSet.WriteImage(hImage, "jpg", 0, SaveImageName);

                }
                
            }
            catch (Exception ex)
            {
                MessageBox.Show("图片保存异常");
                PublicFuntions.SaveErrorLog(PublicValue.LogPath, ex.ToString());
            }
        }

        /// <summary>
        /// 保存窗口图片，jpg格式
        /// </summary>
        /// <param name="windowID"></param>
        /// <param name="path"></param>
        /// <param name="isOK"></param>
        public static void SaveWinImagebyPath(HTuple windowID, string path, bool isOK)
        {
            string SubImageFolder = null;
            HObject windowImage = null;
            HOperatorSet.GenEmptyObj(out windowImage);
            try
            {
                if (isOK) { SubImageFolder = path + "\\OKImage\\" + System.DateTime.Now.ToString("yyyyMMdd"); }
                else { SubImageFolder = path + "\\NGImage\\" + System.DateTime.Now.ToString("yyyyMMdd"); }
                PublicFuntions.CreateFile(SubImageFolder);
                string NowTime = System.DateTime.Now.ToString("yyyyMMddHHmmss");
                HOperatorSet.DumpWindowImage(out windowImage, windowID);
                string ProcessImageName = SubImageFolder + "\\" + NowTime + "_0.jpg";                     //效果图保存为jpg格式,png压缩费时间
                HOperatorSet.WriteImage(windowImage, "jpg", 0, ProcessImageName);
                windowImage.Dispose();
            }
            catch (Exception ex)
            {
                windowImage.Dispose();
                MessageBox.Show("图片保存异常");
                PublicFuntions.SaveErrorLog(PublicValue.LogPath, ex.ToString());
            }
        }
        /// <summary>
        /// 保存图片，JPG格式
        /// </summary>
        /// <param name="hImage"></param>
        /// <param name="path"></param>
        /// <param name="isOK"></param>
        public static void SaveImagebyPathSN(string SN,HObject hImage, string path, bool isOK)
        {
            string SubImageFolder = null;
            try
            {
                string SNname = null;
                string SaveImageName = null;
                if (isOK)

                {
                    SubImageFolder = path +"\\" + System.DateTime.Now.ToString("yyyyMMdd");
                    PublicFuntions.CreateFile(SubImageFolder);
                    SNname = SN+"-OK";                                                             //
                    SaveImageName = SubImageFolder + "\\" + SNname + ".jpg";                        //ok原图保存为jpg格式
                    HOperatorSet.WriteImage(hImage, "jpg", 0, SaveImageName);

                }
                else
                {
                    SubImageFolder = path + "\\" +  System.DateTime.Now.ToString("yyyyMMdd");
                    PublicFuntions.CreateFile(SubImageFolder);
                    SNname = SN + "-NG";
                    SaveImageName = SubImageFolder + "\\" + SNname + ".jpg";                        //ng原图保存为jpg格式
                    HOperatorSet.WriteImage(hImage, "jpg", 0, SaveImageName);

                }

            }
            catch (Exception ex)
            {
                MessageBox.Show("图片保存异常");
                PublicFuntions.SaveErrorLog(PublicValue.LogPath, ex.ToString());
            }
        }
        /// <summary>
        /// 保存日志运行记录
        /// </summary>
        public static void SaveLog(string Path, string LogMessage)
        {
            try
            {
                string LogPath = Path + "//" + System.DateTime.Now.ToString("yyyyMMdd") + ".txt";
                CreateFile(Path);
                System.IO.File.AppendAllText(LogPath, "\r\n" + LogMessage);
            }
            catch (Exception ex)
            {
                SaveErrorLog(PublicValue.LogPath, "SaveLog::" + ex.ToString());
            }
        }

        /// <summary>
        /// 保存异常日志
        /// </summary>
        /// <param name="path：路径"></param>
        /// <param name="ErrorMessage：错误信息"></param>
        public static void SaveErrorLog(string path, string ErrorMessage)
        {
            try
            {
                string LogPath = path + "//" + System.DateTime.Now.ToString("yyyyMMdd") + "ErrorLog.txt";
                CreateFile(path);
                string SaveErrorData = DateTime.Now.ToString("HH:mm:ss") + ">>>" + ErrorMessage;
                System.IO.File.AppendAllText(LogPath, "\r\n" + SaveErrorData);
            }
            catch (Exception)
            {

            }
            
        }

        /// <summary>
        /// 固定间隔删除文件
        /// </summary>
        /// <param name="FilePath"></param>
        /// <param name="Interval"></param>
        public static void DeleateFile(string FilePath, int Interval)
        {
            try
            {
                DirectoryInfo rootDirInfo = new DirectoryInfo(FilePath);
                if (!rootDirInfo.Exists) { return; }
                DateTime NowTime = DateTime.Now;
                FileSystemInfo[] dirs = rootDirInfo.GetFileSystemInfos();

                foreach (var item in dirs)
                {
                    DateTime CreateFileTime = item.CreationTime;
                    TimeSpan OutTime = NowTime - CreateFileTime;
                    if (OutTime.Days > Interval)
                    {
                        FileAttributes Attr = File.GetAttributes(item.FullName);
                        if (Attr == FileAttributes.Directory) { Directory.Delete(item.FullName, true); }
                        else { item.Delete(); }
                    }
                }
            }
            catch (Exception ex)
            {
                SaveErrorLog(PublicValue.LogPath,"DeleateFile::" + ex.ToString());
            }
        }

        //检索halcon函数
        public static string[] GetProcedures(string path)
        {
            string[] result = null;
            HDevProgram IHdevProgramtemp = null;
            HTuple PradecureName = null;
            try
            {

                IHdevProgramtemp = new HDevProgram(path);
                PradecureName = IHdevProgramtemp.GetUsedProcedureNames();
                
                result = PradecureName.SArr;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            return result;
        }
        //打开一个halcon函数
        public static Boolean IsopenHdp(string path)
        {
            HDevProgram IHdevProgramtemp = null;
            try
            {
                IHdevProgramtemp = new HDevProgram(path);
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
           
        }
        /// <summary>
        /// 返回解决方案的路径
        /// </summary>
        /// <returns></returns>
        public static string FindSolutionPath()
        {
            string startpath = AppDomain.CurrentDomain.BaseDirectory;
            DirectoryInfo currentDir = new DirectoryInfo(startpath);
            while (currentDir != null)
            {
                // 查找 .sln 文件来确定解决方案文件夹
                if (currentDir.GetFiles("*.sln").Length > 0)
                {
                    return currentDir.FullName;
                }
                currentDir = currentDir.Parent;
            }
            return null;


        }




        public static void SaveAsCSV(string FilePath, string mes)
        {
            //先判断路径是否有，没有追加
            string CSVPath = FilePath + "\\" + System.DateTime.Now.ToString("yyyyMMdd") + ".csv";
            CreateFile(FilePath);
            //添加内容就可以了,如果出现问题
            System.IO.StreamWriter Record = new System.IO.StreamWriter(CSVPath, true, System.Text.Encoding.UTF8);
            Record.WriteLine(mes);
            Record.Flush();
            Record.Close();
            Record.Dispose();
        }
        /// <summary>
        /// 读取最新的文件名和时间
        /// </summary>
        /// dir：目标文件夹  ext:文件格式后缀  
        public  class FileTimeInfo
        {
            public string FileName;  //文件名
            public DateTime FileCreateTime; //创建时间
        }
        public static FileTimeInfo GetLatestFileTimeInfo(string dir, string ext)
        {
            List<FileTimeInfo> list = new List<FileTimeInfo>();
            DirectoryInfo d = new DirectoryInfo(dir);
            foreach (FileInfo file in d.GetFiles())
            {
                if (file.Extension.ToUpper() == ext.ToUpper())
                {
                    list.Add(new FileTimeInfo()
                    {
                        FileName = file.FullName,
                        FileCreateTime = file.CreationTime
                    });
                }
            }
            var f = from x in list
                    orderby x.FileCreateTime
                    select x;
            return f.LastOrDefault();
        }
        /// <summary>
        /// 位图转Hobj（单通道）
        /// </summary>
        /// <param name="bitmap"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentException"></exception>
        public static HObject BitmapToHObject1(Bitmap bitmap)
        {
            // 确保Bitmap是8位灰度图
            if (bitmap.PixelFormat != PixelFormat.Format8bppIndexed)
            {
                throw new ArgumentException("仅支持单通道8位灰度图像！");
            }

            // 获取图像尺寸
            int width = bitmap.Width;
            int height = bitmap.Height;

            // 3. 锁定位图数据并获取像素值
            BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height),
                                                    ImageLockMode.ReadOnly,
                                                    PixelFormat.Format8bppIndexed);

            int stride = bitmapData.Stride;
            IntPtr ptr = bitmapData.Scan0;
            byte[] pixelData = new byte[stride * height];

            // 复制位图数据到字节数组
            Marshal.Copy(ptr, pixelData, 0, pixelData.Length);

            // 4. 释放锁定
            bitmap.UnlockBits(bitmapData);

            // 5. 创建Halcon图像
            HObject hImage;
            HOperatorSet.GenImage1Extern(out hImage, "byte", width, height, ptr, IntPtr.Zero);

            return hImage;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="bitmap"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentException"></exception>
        public static HObject ConvertBitmapToHObject(Bitmap bitmap)
        {
            // 检查是否为24位位图
            if (bitmap.PixelFormat != System.Drawing.Imaging.PixelFormat.Format24bppRgb)
            {
                throw new ArgumentException("输入的位图必须是24位RGB格式。");
            }

            int width = bitmap.Width;
            int height = bitmap.Height;

            // 锁定位图数据
            System.Drawing.Imaging.BitmapData bitmapData = bitmap.LockBits(
                new Rectangle(0, 0, width, height),
                System.Drawing.Imaging.ImageLockMode.ReadOnly,
                System.Drawing.Imaging.PixelFormat.Format24bppRgb);

            try
            {
                // 获取位图数据的指针
                IntPtr pointer = bitmapData.Scan0;

                // 创建Halcon的HObject对象
                HObject hObject;
                HOperatorSet.GenImageInterleaved(out hObject, pointer, "rgb", width, height, 0, "byte", 0, 0, 0, 0, -1, 0);

                return hObject;
            }
            finally
            {
                // 解锁位图数据
                bitmap.UnlockBits(bitmapData);
            }
        }

        /// <summary>
        /// 位图转Hobj（3通道）
        /// </summary>
        /// <param name="bitmap"></param>
        /// <returns></returns>
        public static HObject BitmapToHObject3(Bitmap bitmap)
        {
            // 生成 Halcon 图像对象
            HObject hImage;
            try 
            { 

                // 获取图像宽度和高度
                int width = bitmap.Width;
                int height = bitmap.Height;

                // 将Bitmap转换为字节数组
                BitmapData bitmapData = bitmap.LockBits(
                    new Rectangle(0, 0, width, height),
                    ImageLockMode.ReadOnly,
                    PixelFormat.Format24bppRgb); // 确保是 24 位 RGB 格式

                int stride = bitmapData.Stride; // 每行的字节数
                IntPtr ptr = bitmapData.Scan0;  // 获取指针

                byte[] pixelValues = new byte[stride * height];
                Marshal.Copy(ptr, pixelValues, 0, pixelValues.Length); // 复制数据到字节数组

                bitmap.UnlockBits(bitmapData); // 解锁位图

                // 由于 Bitmap 以 BGR 存储，我们需要转换为 RGB
                byte[] rChannel = new byte[width * height];
                byte[] gChannel = new byte[width * height];
                byte[] bChannel = new byte[width * height];

                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        int indexBitmap = y * stride + x * 3;
                        int indexHalcon = y * width + x;

                        bChannel[indexHalcon] = pixelValues[indexBitmap];     // B
                        gChannel[indexHalcon] = pixelValues[indexBitmap + 1]; // G
                        rChannel[indexHalcon] = pixelValues[indexBitmap + 2]; // R
                    }
                }

                
                HOperatorSet.GenImage3(out hImage, "byte", width, height,
                                       new HTuple(bChannel),
                                       new HTuple(gChannel),
                                       new HTuple(rChannel));

                return hImage;


            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return null;
            }
}

    }
}


